/**
 * @fileOverview The "indydialogui" plugin.
 */
VED.plugins.add( 'indydialogui', {
   onLoad: function() {

      var initPrivateObject = function( elementDefinition ) {
            this._ || ( this._ = {} );
            this._[ 'default' ] = this._.initValue = elementDefinition[ 'default' ] || '';
            this._.required = elementDefinition[ 'required' ] || false;
            var args = [ this._ ];
            for ( var i = 1; i < arguments.length; i++ )
               args.push( arguments[ i ] );
            args.push( true );
            VED.tools.extend.apply( VED.tools, args );
            return this._;
         },
         textBuilder = {
            build: function( dialog, elementDefinition, output ) {
               return new VED.ui.dialog.textInput( dialog, elementDefinition, output );
            }
         },
         commonBuilder = {
            build: function( dialog, elementDefinition, output ) {
               return new VED.ui.dialog[ elementDefinition.type ]( dialog, elementDefinition, output );
            }
         },
         containerBuilder = {
            build: function( dialog, elementDefinition, output ) {
               var children = elementDefinition.children,
                  child,
                  childHtmlList = [],
                  childObjList = [];
               for ( var i = 0;
               ( i < children.length && ( child = children[ i ] ) ); i++ ) {
                  var childHtml = [];
                  childHtmlList.push( childHtml );
                  childObjList.push( VED.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );
               }
               return new VED.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );
            }
         },
         commonPrototype = {
            isChanged: function() {
               return this.getValue() != this.getInitValue();
            },

            reset: function( noChangeEvent ) {
               this.setValue( this.getInitValue(), noChangeEvent );
            },

            setInitValue: function() {
               this._.initValue = this.getValue();
            },

            resetInitValue: function() {
               this._.initValue = this._[ 'default' ];
            },

            getInitValue: function() {
               return this._.initValue;
            }
         },
         commonEventProcessors = VED.tools.extend( {}, VED.ui.dialog.uiElement.prototype.eventProcessors, {
            onChange: function( dialog, func ) {
               if ( !this._.domOnChangeRegistered ) {
                  dialog.on( 'load', function() {
                     this.getInputElement().on( 'change', function() {
                        // Make sure 'onchange' doesn't get fired after dialog closed. (#5719)
                        if ( !dialog.parts.dialog.isVisible() )
                           return;

                        this.fire( 'change', { value: this.getValue() } );
                     }, this );
                  }, this );
                  this._.domOnChangeRegistered = true;
               }

               this.on( 'change', func );
            }
         }, true ),
         eventRegex = /^on([A-Z]\w+)/,
         cleanInnerDefinition = function( def ) {
            // An inner UI element should not have the parent's type, title or events.
            for ( var i in def ) {
               if ( eventRegex.test( i ) || i == 'title' || i == 'type' )
                  delete def[ i ];
            }
            return def;
         };

      VED.tools.extend( VED.ui.dialog, {
         
         editableCombo: function( dialog, elementDefinition, htmlList ) {
            if ( arguments.length < 3 )
               return;
               
            var _ = initPrivateObject.call( this, elementDefinition );
            
            if ( elementDefinition.validate )
               this.validate = elementDefinition.validate;
            
            var _id = VED.tools.getNextId()
            _.inputId = _id + '_editable_combo';
            _.textId = _.inputId + '_text';
            
            var innerHTML = function() {
               var myDefinition = VED.tools.extend( {}, elementDefinition, {
                  id: elementDefinition.id ? elementDefinition.id + '_editable_combo' : VED.tools.getNextId() + '_editable_combo'
               }, true ),
                  html = [],
                  optionsHTML = [],
                  selectAttributes = { 'id': _.inputId, 'class': 'ved_dialog_ui_input_select', 'aria-labelledby': this._.labelId },
                  textAttributes = { 'id': _.textId, 'class': 'ved_dialog_ui_input_text', 'aria-labelledby': this._.labelId };

               html.push( '<div class="ved_dialog_ui_input_', elementDefinition.type, '" role="presentation" style="' );
               html.push( 'position:relative;height:19px;' );
               if ( elementDefinition.width )
                  html.push( 'width:' + elementDefinition.width + ';' );
               html.push( '">' );

               // Add multiple and size attributes from element definition.
               if ( elementDefinition.size != undefined ) {
                  textAttributes.size = selectAttributes.size = elementDefinition.size;
               }
               if ( elementDefinition.multiple != undefined )
                  selectAttributes.multiple = elementDefinition.multiple;

               cleanInnerDefinition( myDefinition );
               
               for ( var i = 0, item; i < elementDefinition.items.length && ( item = elementDefinition.items[ i ] ); i++ ) {
                  optionsHTML.push( '<option value="', VED.tools.htmlEncode( item[ 1 ] !== undefined ? item[ 1 ] : item[ 0 ] ).replace( /"/g, '&quot;' ), '" /> ', VED.tools.htmlEncode( item[ 0 ] ) );
               }

               if ( typeof myDefinition.inputStyle != 'undefined' )
                  myDefinition.style = myDefinition.inputStyle;

               var selectStyles = {
                  position: 'absolute',
                  top: 0,
                  left: 0
               };
               
               textAttributes.type = 'text';
               var textStyles = {
                  position: 'absolute',
                  top: 0,
                  left: 0,
                  margin: '1px'
               };
               
               selectStyles.width = ( elementDefinition.width ? parseInt(elementDefinition.width) : 150 ) + 'px';
               textStyles.width   = ( elementDefinition.width ? parseInt(elementDefinition.width) - 18 : 132 ) + 'px';
               
               _.select = new VED.ui.dialog.uiElement( dialog, myDefinition, html, 'select', selectStyles, selectAttributes, optionsHTML.join( '' ) );
               _.text = new VED.ui.dialog.uiElement( dialog, myDefinition, html, 'input', textStyles, textAttributes );

               html.push( '</div>' );

               return html.join( '' );
            };

            VED.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );
            
            
            
            
         }
         
      }, true );

      /** @class VED.ui.dialog.editableCombo */
      VED.ui.dialog.editableCombo.prototype = VED.tools.extend( new VED.ui.dialog.labeledElement, {

         getInputElement: function() {
            return this._.select.getElement();
         },

         getTextElement: function() {
            return this._.text.getElement();
         },

         add: function( label, value, index ) {
            var option = new VED.dom.element( 'option', this.getDialog().getParentEditor().document ),
               selectElement = this.getInputElement().$;
            option.$.text = label;
            option.$.value = ( value === undefined || value === null ) ? label : value;
            if ( index === undefined || index === null ) {
               if ( VED.env.ie )
                  selectElement.add( option.$ );
               else
                  selectElement.add( option.$, null );
            } else
               selectElement.add( option.$, index );
            return this;
         },

         remove: function( index ) {
            var selectElement = this.getInputElement().$;
            selectElement.remove( index );
            return this;
         },

         clear: function() {
            var selectElement = this.getInputElement().$;
            while ( selectElement.length > 0 )
               selectElement.remove( 0 );
            return this;
         },
         
         eventProcessors: VED.tools.extend( {}, VED.ui.dialog.uiElement.prototype.eventProcessors, {
            onChange: function( dialog, func ) {
               dialog.on( 'load', function() {
                  var text_el   = this.getTextElement(),
                      select_el = this.getInputElement(),
                      options = select_el.getChildren(),
                      count = options.count(),
                      i;

                  select_el.on('change', function(evt) {
                     console.log(this);
                  });
                  
                  text_el.on('keyup', function(evt) {
                     var text = text_el.getValue().ltrim(),
                         reg = new RegExp( text, 'i' ),
                         matched = [];

                     if( text ) {
                        for( i=0; i<count; i++  ) {
                           var option = options.getItem(i);
                           if( option.getText().ltrim().search(reg) === 0 ) {
                              matched.push({ id:option.getValue(), text: option.getText().ltrim() });
                           }
                        }
                        
                        if( matched.length == 1 ) {
                           text_el.setValue( matched[0].text );
                           select_el.setValue( matched[0].id );
                        } else if( matched.length > 1 ) {
                           text_el.setValue( matched[0].text );
                           text_el.$.selectionStart = text.length;
                           text_el.$.selectionEnd   = matched[0].text.length;
                           select_el.setValue( matched[0].id );
                           
                        } else {
                           select_el.setValue('');
                        }
                        
                        // console.log( matched );
                     }
                     
                     
                  });

                  /*
                  var children = this._.children,
                     me = this;
                  for ( var i = 0; i < children.length; i++ ) {
                     var element = children[ i ].getElement();
                     element.on( 'propertychange', function( evt ) {
                        evt = evt.data.$;
                        if ( evt.propertyName == 'checked' && this.$.checked )
                           me.fire( 'change', { value: this.getAttribute( 'value' ) } );
                     });
                  }
                  */
               }, this );
               this.on( 'change', func );
               
               return null;
            }
         }, true ),

         keyboardFocusable: true
      }, commonPrototype, true );

      VED.ui.dialog.fileButton.prototype = new VED.ui.dialog.button;

      VED.ui.dialog.fieldset.prototype = VED.tools.clone( VED.ui.dialog.hbox.prototype );

      VED.dialog.addUIElement( 'editableCombo', commonBuilder );
   }
});






